# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import time
from typing import List
from tortoise.queryset import Q
from tortoise.transactions import in_transaction
from hypertext import PagingResult
from common.utils.urls import UrlUtil
from common.models.users import UserModel
from common.models.agents import AgentKnowModel
from common.postgres.public import PgKnowledgeModel, PgAttachmentModel
from apps.admin.schemas.agent.know import dataset_schema as schema


class KnowDatasetService:

    @classmethod
    async def lists(cls, params: schema.KnowDatasetSearchIn) -> PagingResult[schema.KnowDatasetListVo]:
        """
        数据列表

        Args:
           params (schema.KnowDatasetSearchIn): 检索条件

        Returns:
            PagingResult[schema.KnowDatasetListVo]

        Author:
           zero
        """
        # 搜索条件
        where = PgKnowledgeModel.build_search({
            "%like%": ["keyword@question"],
            "=": ["status"]
        }, params.__dict__)

        where.append(Q(is_delete=0))
        if params.archive_id:
            where.append(Q(archive_id=params.archive_id))

        # 查询数据
        _model = PgKnowledgeModel.filter(*where).order_by("-create_time", "chunk_index")
        _pager = await PgKnowledgeModel.paginate(
            model=_model,
            page_no=params.page_no,
            page_size=params.page_size
        )

        # 所属用户
        user_ids = [int(item["user_id"]) for item in _pager.lists if item["user_id"]]
        users: dict = await UserModel.queryUserDictsById(user_ids)

        # 知识库
        know_ids = [int(item["know_id"]) for item in _pager.lists if item["know_id"]]
        knows: dict = await AgentKnowModel.queryKnowDictsById(know_ids, field=["id", "name"])

        # 处理数据
        _lists = []
        for item in _pager.lists:
            know = knows.get(item["know_id"], {})
            user = users.get(item["user_id"], {})
            _lists.append(schema.KnowDatasetListVo(
                id=str(item.get("uuid")),
                question=item.get("question") or "",
                answer=item.get("answer") or "",
                know=know.get("name") or "",
                know_code=know.get("code") or "",
                vector_alias=item.get("vector_alias") or "",
                vector_model=item.get("vector_model") or "",
                dimension=int(item.get("dimension")),
                character=len(item.get("question") or "") + len(item.get("answer") or ""),
                status=item["status"],
                is_disable=item["is_disable"],
                create_time=item["create_time"],
                update_time=item["create_time"],
                user={
                    "sn": user.get("sn", "").strip(),
                    "nickname": user.get("nickname", ""),
                    "mobile": user.get("mobile", ""),
                    "avatar": await UrlUtil.to_absolute_url(user.get("avatar", ""))
                }
            ))

        _pager.lists = _lists
        return _pager

    @classmethod
    async def detail(cls, uuid_: str) -> schema.KnowDatasetDetailVo:
        """
        数据详情信息

        Args:
            uuid_ (str): 数据的UUID

        Returns:
            schema.KnowDatasetDetailVo

        Author:
            zero
        """
        # 查询数据
        detail = await PgKnowledgeModel.filter(uuid=uuid_).get()

        # 获取附件
        annex = []
        attachment = await (PgAttachmentModel
                            .filter(dataset_id=detail.uuid, is_delete=0)
                            .order_by("sort")
                            .all())

        # 处理附件
        for att in attachment:
            annex.append(schema.KnowDatasetAnnex(
                id=str(att.uuid),
                type=att.type,
                name=str(att.name),
                path=await UrlUtil.to_absolute_url(att.path),
                size=att.size,
                ext=att.ext,
                sort=att.sort,
                question=att.question
            ))

        # 返回结果
        return schema.KnowDatasetDetailVo(
            id=str(uuid_),
            question=detail.question,
            answer=detail.answer,
            annex=annex
        )

    @classmethod
    async def delete(cls, uuids: List[str]) -> None:
        """
        数据删除

        Args:
            uuids (List[str]): 数据ID

        Author:
            zero
        """
        async with in_transaction("pgsql"):
            # 删除附件
            await PgAttachmentModel.filter(dataset_id__in=uuids).update(
                is_delete=1,
                delete_time=int(time.time())
            )

            # 删除数据
            await (PgKnowledgeModel
                   .filter(uuid__in=uuids, is_delete=0)
                   .update(
                        is_delete=1,
                        delete_time=int(time.time())
                   ))
